﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using com.nm.interfaces;
using System.Web.Caching;

namespace com.nm.library.Factorys {
	/// <summary>
	/// 
	/// </summary>
	public class TaskFactory : ITaskFactory {
		static IDictionary<string, TaskData> _taskList = new Dictionary<string, TaskData>();  
		/// <summary>
		/// 注册任务（会自动启动）
		/// </summary>
		/// <param name="title"></param>
		/// <param name="interval"></param>
		/// <param name="handler"></param>
		/// <returns></returns>
		public bool Register(string title, int interval, EventHandler handler) {
			if(string.IsNullOrWhiteSpace(title)
				|| interval < 1
				|| handler == null)
				return false;
			if (_taskList.ContainsKey(title)){
				if(_taskList[title].Interval != interval){
					_taskList[title]
						.Stop()
						.Start(interval);
				}
				return true;
			}
			var item = new TaskData() {
				Title = title,
				Interval = interval,
				Handler = handler
			};
			item.Start();
			_taskList.Add(title, item);
			return true;
		}

		/// <summary>
		/// 停止
		/// </summary>
		/// <param name="title"></param>
		public void Stop(string title) {
			if(!_taskList.ContainsKey(title))
				return;
			_taskList[title].Stop();
		}
		/// <summary>
		/// 启动，如果已经启动则无视
		/// </summary>
		/// <param name="title"></param>
		/// <returns></returns>
		public bool Start(string title) {
			if (!_taskList.ContainsKey(title))
				return false;
			if(_taskList[title].IsStop)
				_taskList[title].Start();
			return true;
		}

		internal class TaskData {

			public string Title { get; set; }

			public int Interval { get; set; }

			public EventHandler Handler { get; set; }

			public bool IsBusy { get; protected set; }
			public bool IsStop { get; protected set; }

			public void Start(){
				this.IsStop = false;
				Log.WriteLines(this.Title, "start");
                //TODO：暂屏蔽
				//HttpRuntime.Cache.Insert($"Tasker {this.Title} {DateTime.Now}", this.Interval, null, DateTime.Now.AddSeconds(this.Interval), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, callBack);
			}
			public TaskData Start(int interval) {
				this.Interval = interval;
				this.Start();
				return this;
			}

			public TaskData Stop(){
				this.IsStop = true;
				return this;
			}

			private void callBack(string key, object value, CacheItemRemovedReason reason) {
				if (IsBusy){
					Log.WriteLines(this.Title, IsBusy, IsStop);
					if(!this.IsStop)
						this.Start();
					return;
				}

				IsBusy = true;
				try{
					this.Handler.Invoke(this, EventArgs.Empty);
				}catch (Exception ex){
					Log.Error(ex, this.Title);
					if (HttpContext.Current != null)
					{
						Log.WriteLines(HttpContext.Current.Request.Url.Host);
					}
					else
					{
						Log.WriteLines("HttpContext.Current == null");
					}
				}
				IsBusy = false;
				Log.WriteLines(this.Title, IsBusy, IsStop);
				if (!this.IsStop)
					this.Start();
			}

		}
	}
}
